package com.nervenets.shopping.controller.user;

import com.nervenets.general.Global;
import com.nervenets.general.entity.ResponseResult;
import com.nervenets.general.jwt.aspect.JwtRole;
import com.nervenets.general.jwt.aspect.JwtSecurity;
import com.nervenets.general.jwt.util.JwtUtils;
import com.nervenets.general.redis.RedisSyncLocker;
import com.nervenets.general.service.GlobalSecurityService;
import com.nervenets.general.web.BaseEntityController;
import com.nervenets.general.web.params.BoolIdParams;
import com.nervenets.shopping.controller.user.dto.ManagerLoginDto;
import com.nervenets.shopping.controller.user.params.ManagerFormParams;
import com.nervenets.shopping.controller.user.params.ManagerPagingParams;
import com.nervenets.shopping.controller.user.params.MobileLoginParams;
import com.nervenets.shopping.exception.UserNotLoginException;
import com.nervenets.shopping.hibernate.domain.user.Manager;
import com.nervenets.shopping.service.ManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

@Api(value = "管理人员接口v1", tags = "管理人员接口")
@RestController
@RequestMapping("/api/manager")
@JwtRole(group = "system", groupName = "系统管理", function = "account", functionName = "账号管理")
public class ManagerController extends BaseEntityController<Manager, ManagerService, ManagerFormParams, ManagerPagingParams, Manager, Manager> {
    @Resource
    private RedisSyncLocker<ResponseEntity<ResponseResult<Manager>>> redisSyncLocker;
    @Resource
    private GlobalSecurityService globalSecurityService;

    @ApiOperation(value = "手机号码密码登录")
    @PostMapping("/login")
    @JwtSecurity(required = false)
    public ResponseEntity<ResponseResult<ManagerLoginDto>> login(@Valid @RequestBody MobileLoginParams params, HttpServletRequest request) {
        final Manager manager = service.findByMobile(params.getUsername());
        if (null == manager) return errorMessage(HttpStatus.NOT_FOUND.value(), "账号或密码不正确");
        if (!manager.isEnable()) return errorMessage(HttpStatus.NOT_FOUND.value(), "该账号已被禁用");
        if (!params.getPassword().equals(manager.getPassword()))
            return errorMessage("您输入的手机号码或密码不正确");

        return successMessage(new ManagerLoginDto(manager, true, JwtUtils.license(request), globalSecurityService, request));
    }

    @ApiOperation(value = "登录信息")
    @PostMapping("/loginInfo")
    public ResponseEntity<ResponseResult<ManagerLoginDto>> loginInfo(HttpServletRequest request) {
        final Manager manager = service.findOne(JwtUtils.getUser().getId());
        if (null == manager) throw new UserNotLoginException();
        return successMessage(new ManagerLoginDto(manager, false, null, globalSecurityService, request));
    }

    @ApiOperation(value = "启用或禁用")
    @PostMapping("/enable")
    @JwtSecurity(permission = "enable", permissionName = "禁用启用")
    public ResponseEntity<ResponseResult<Manager>> enable(@Valid @RequestBody BoolIdParams params) throws Exception {
        return redisSyncLocker.idLock(params.getTargetId(), () -> {
            Manager manager = service.findById(params.getTargetId()).orElse(null);
            if (null == manager) return errorMessage(HttpStatus.NOT_FOUND.value(), "您操作的账号不存在");

            manager.setEnable(params.isYes());
            service.save(manager);
            return successMessage(manager);
        });
    }

    @ApiOperation(value = "退出登录")
    @PostMapping("/logout")
    public ResponseEntity<ResponseResult<Void>> logout(HttpServletRequest request) throws Exception {
        globalSecurityService.logout(request.getHeader(Global.Constants.TOKEN_KEY), JwtUtils.license(request));
        return successMessage();
    }
}
